package com.magold.logic.region.airflow;

import org.andengine.entity.scene.Scene;
import org.andengine.entity.shape.IAreaShape;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.magold.logic.ISpriteLogic;
import com.magold.logic.LogicComponentFinder;
import com.magold.logic.LogicPhysicsHelper;
import com.magold.logic.LogicSpriteWrapper;
import com.magold.logic.exception.SelfCollisionException;
import com.magold.logic.filter.BaseCollisionFilter;
import com.magold.logic.filter.CollisionFilter;
import com.magold.logic.filter.LogicCollisionFilter;
import com.magold.physics.MagoldPhysicsConnector;
import com.magold.sprite.IMultiTextureSprite;
import com.magold.sprite.MultiTextureSprite;

public class ParticleLogic implements ISpriteLogic {
	// static.
	static VertexBufferObjectManager sVertexBufferObjectManager;
	static ITiledTextureRegion sTexture;
	public static void customize(VertexBufferObjectManager pVBOM, ITiledTextureRegion pTexture) {
		sVertexBufferObjectManager = pVBOM;
		sTexture = pTexture;
	}
	
	// ======================================================================================
	
	private IParticleRecycleHandler<IMultiTextureSprite> mRecycleHandler;
	private MagoldPhysicsConnector mConnector;
	private float mMass;
	IMultiTextureSprite mSprite;
	
	public ParticleLogic(IParticleRecycleHandler<IMultiTextureSprite> pRecycleHandler) {
		mRecycleHandler = pRecycleHandler;
	}
	
	@Override
	public MagoldPhysicsConnector findPhysicsConnector(IAreaShape pShape) {
		if (mSprite == pShape) return mConnector;
		
		return null;
	}
	

	@Override
	public void createSceneData(float pX, float pY, float pRotation, float pScale, Scene pScene) {
		IMultiTextureSprite raw = new MultiTextureSprite(pX, pY, 0, sTexture, sVertexBufferObjectManager);
		
		mSprite = LogicSpriteWrapper.wrap(raw, 1, null, this, pRotation, pScene);
	}

	@Override
	public void createPhysicsData(PhysicsWorld pWorld) {
		FixtureDef fDef = PhysicsFactory.createFixtureDef(0, 0, 0, true);
		Body body = PhysicsFactory.createBoxBody(pWorld, mSprite, BodyType.KinematicBody, fDef);
		mMass = 1.0f;
		
		mConnector = LogicPhysicsHelper.connectBody(pWorld, body, mSprite);
	}

	@Override
	public boolean isStatic() {
		return false;
	}

	private CollisionFilter mFilter = new LogicCollisionFilter(true, true, false, false).filter(new BaseCollisionFilter() {
		
		@Override
		public boolean accept(ISpriteLogic pLogic, Contact pContact) {
			return ! (pLogic instanceof ParticleLogic);
		}
	});
		
	@Override
	public void startCollide(ISpriteLogic pAnthor, Contact pContact) {
		if (!mFilter.accept(pAnthor, pContact)) return;
		
		Vector2 v = mConnector.getBody().getLinearVelocity();
		
		try {
			Body b = LogicComponentFinder.findBody(pAnthor, pContact);
			b.applyLinearImpulse(v.mul(mMass), b.getWorldCenter());
			mRecycleHandler.recycle(mSprite);
		} catch (SelfCollisionException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void endCollide(ISpriteLogic pAnthor, Contact pContact) {

	}

}
